package ve.gob.ine.censo.service;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import ve.gob.ine.censo.beans.Encriptacion;
import ve.gob.ine.censo.beans.FunctionByte;
import ve.gob.ine.censo.beans.TripleDES;
import ve.gob.ine.censo.dao.ibatis.Conexion;
import ve.gob.ine.censo.dao.ibatis.sis_reportes.UsuarioMapper;
import ve.gob.ine.censo.model.sis_reportes.Rol;
import ve.gob.ine.censo.model.sis_reportes.Usuario;
import ve.gob.ine.censo.model.sis_reportes.UsuarioExample;

public class UsuarioServiceImpl  implements AuthenticationProvider {

	private GrantedAuthority[] makeGrantedAuthorities(Usuario usuario) {
		
		GrantedAuthority[] result = null;
		
		SqlSession sqlSession = Conexion.config().openSession();
		
		try {
			List<Rol> roles = sqlSession.selectList("usuarioRolUser.selectRolesAndGruposByUsuarioId", usuario);			

			result = new GrantedAuthority[roles.size()];
			
			int i = 0;
			for (Rol rol : roles) {
				System.out.println("Aut: "+rol.getNombre());
				result[i++] = new GrantedAuthorityImpl(rol.getNombre());
			}

		} finally {
			sqlSession.close();
		}
		return result;
	}

	public Authentication authenticate(Authentication auth) throws AuthenticationException {
		
		SqlSession sqlSession = Conexion.config().openSession();
		
		System.out.println("username::"+auth.getName());
		UsuarioExample example = new UsuarioExample();
		example.createCriteria().andUsuarioLike(auth.getName()+"%");
		
		List<Usuario> usuarios = null;
		
		try {
			usuarios = sqlSession.getMapper(UsuarioMapper.class).selectByExample(example);
		} finally {
			sqlSession.close();
		}
		
		for (Usuario usuario : usuarios) {
			if (usuario == null)
				
				throw new UsernameNotFoundException("User not found: " + auth.getName());
			else if (isAutentication(usuario.getClave(), (String) auth.getCredentials())) 

				return new UsernamePasswordAuthenticationToken(auth.getName(), auth.getCredentials(), makeGrantedAuthorities(usuario));
		}

		throw new BadCredentialsException("Usuario o contrase�a incorrecto");
	}
	
	public static boolean isAutentication(String dbPassword, String password){
		
		//ENCRIPTADO HECHO EN CASA
//		System.out.println("ENCRIPTADO HECHO EN CASA");
//		Encriptacion esource = new Encriptacion();
//		String key = "DC101AB52CF894CEE52F61731643B94F";
//		byte[] keyb = FunctionByte.hex2byte(key);
//	    dbPassword = esource.Decrypt(keyb, FunctionByte.hex2byte(dbPassword));
	    return dbPassword.equals(password);
	}	

	@SuppressWarnings("rawtypes")
	public boolean supports(Class authentication) {
		return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
	}
}
